import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.net.*;
import javax.net.ssl.*;


public class SSLConection{
  
  /**
   * KeyStore for storing our public/private key pair
   */
  private KeyStore localKeyStore;
  
  /**
   * KeyStore for storing the server's public key
   */
  private KeyStore remoteKeyStore;

  /**
   * Used to generate a SocketFactory
   */
  private SSLContext sslContext;
  
  /**
   * Passphrase for accessing our authentication keystore
   */
  private String passphrase;

  /**
   * A source of secure random numbers
   */
  private SecureRandom secureRandom;

  private String host;
  private int port;

  private String privateKeystorePath;
  private String publicKeystorePath;

  /**
   * Constructor
   */

  public SSLConection(String host, int port, String privateKeystore, String publicKeystore, String passphrase){
    
    this.secureRandom = new SecureRandom();
    secureRandom.nextInt();
    this.host = host;
    this.port = port;
    this.privateKeystorePath = privateKeystore; 
    this.publicKeystorePath = publicKeystore;
    this.passphrase = passphrase;
  }

  /**
   * Constructor sin host para servers
   */

  public SSLConection(int port, String privateKeystore, String publicKeystore, String passphrase){
    
    this.secureRandom = new SecureRandom();
    secureRandom.nextInt();
    this.port = port;
    this.privateKeystorePath = privateKeystore; 
    this.publicKeystorePath = publicKeystore;
    this.passphrase = passphrase;
  }
      
  public SSLSocket getSSLSocket() throws Exception{

    setupRemoteKeystore();
    setupLocalKeyStore();
    setupSSLContext();
    SSLSocketFactory sf = sslContext.getSocketFactory();
    return (SSLSocket)sf.createSocket( this.host, this.port );
  }

  public SSLServerSocket getSSLServerSocket() throws Exception{
    setupRemoteKeystore();
    setupLocalKeyStore();
    setupSSLContext();
    SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
    SSLServerSocket ss = (SSLServerSocket)sf.createServerSocket( this.port );
    ss.setNeedClientAuth(true);
    return ss;
    
  }

  private void setupRemoteKeystore() throws GeneralSecurityException, IOException {
    remoteKeyStore = KeyStore.getInstance( "JKS" );
    remoteKeyStore.load( new FileInputStream( this.publicKeystorePath ), 
                        "public".toCharArray() );
  }

  private void setupLocalKeyStore() throws GeneralSecurityException, IOException {
    localKeyStore = KeyStore.getInstance( "JKS" );
    localKeyStore.load( new FileInputStream( this.privateKeystorePath ),
                       passphrase.toCharArray() );
  }

  private void setupSSLContext() throws GeneralSecurityException, IOException {
    TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
    tmf.init( remoteKeyStore );

    KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
    kmf.init( localKeyStore, passphrase.toCharArray() );

    sslContext = SSLContext.getInstance( "TLS" );
    sslContext.init( kmf.getKeyManagers(),
                     tmf.getTrustManagers(),
                     secureRandom );
  }

}